﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GenericGA.extrandom;

namespace GenericGA.generationmaker.mutation
{
    /// <summary>
    /// Mutate a chromosome by flipping each bit using a probability.
    /// </summary>
    public class SinglePointMutation : Mutation
    {

        /// <summary>
        /// A random number generator.
        /// </summary>
        private readonly ExtRandom randGen;

        /// <summary>
        /// The probability that each bit in the chromosome will be flipped.
        /// </summary>
        public double MutationRate {
            get
            {
                return mutationRate;
            }
            set {
                if (value < 0.0 || value > 1.0)
                {
                    throw new ArgumentException();
                }
                mutationRate = value;
            }
        }
        private double mutationRate;

        /// <summary>
        /// Constructor to create a SinglePointMutation object using a mutation rate.
        /// </summary>
        /// <param name="randGen">A random number generator.</param>
        /// <param name="mutationRate">The probability for each bit in the chromosome to flip.</param>
        public SinglePointMutation(ExtRandom randGen, double mutationRate)
        {
            this.randGen = randGen;
            this.MutationRate = mutationRate;
        }

        /// <summary>
        /// Flip each bit in the chromosome according to a probability.
        /// </summary>
        /// <param name="bits">The chromosome to mutate.</param>
        public override void Mutate(List<ulong> mutant)
        {
            for (int i = 0; i < mutant.Count; i++)
            {
                Mutation.FlipBits(mutant, i, randGen.NextULongMask(MutationRate));
            }
        }

    }
}
